package main

import (
	"fmt"
	"sync"
)

var wg sync.WaitGroup

// 想intChan放入1-120000个数
func putNum(intchan chan int) {
	for i := 2; i < 100; i++ {
		intchan <- i
	}
	close(intchan)
	wg.Done()
}
// 从intChan取出数据，并判断是否为素数，如果是就把得到的素数放在primeChan里
func primeNum(intChan chan int, primeChan chan int,exitChan chan bool) {
	for num := range intChan {
		var flag = true
		for i := 2; i < num; i++ {
			if num%i == 0 {
				flag = false
				break
			}
		}
		if flag {
			primeChan <- num //num是素数
		}
	}
	// 要关闭primeChan
	// 如果一个channel关闭无法再存放数据
	// 什么时候关闭primeChan

	// 给exitChan存放一条数据
	exitChan <- true
		wg.Done()
}

// printPrime打印素数的方法
func printPrime(primeChan chan int) {
	for v := range primeChan {
		fmt.Println(v)
	}
		wg.Done()
}

func main() {
	// start :=time.Now().Unix()

	intChan := make(chan int, 1000)
	primeChan := make(chan int, 100)
	exitChan  :=make(chan bool,16)  //表示primeChan close
	// 存放素数的协程
	wg.Add(1)
	go putNum(intChan)
	// 统计素数的协程
	for i := 0; i < 16; i++ {
		wg.Add(1)
		go primeNum(intChan, primeChan,exitChan)
	}
	// 打印素数的协程
	wg.Add(1)
	go printPrime(primeChan)
	// 判断exitChan是否存满值
	wg.Add(1)
	go func(){
		for i:=0;i<16;i++{
			<- exitChan
		}
		// 关闭primeChan
		close(primeChan)
		wg.Done()
	}()
	// 等待协程完毕
	// end :=time.Now().Unix()
	// printPrime(end-start)
	wg.Wait()
	fmt.Println("执行完毕")

}